package com.lzp.util;

import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.*;

import java.io.File;
import java.io.IOException;

public class VideoUtil {

    /**
     * 压缩视频
     * @param multipartFile     数据源
     * @param maxFileSize       压缩后最大体积 指视频大小，不包含音频内容，加上音频后文件总大小稍大于这个值 1-2M （单位：MB）
     * @param maxVideoBitRate        压缩后视频最大比特率
     * @return
     */
    public static byte[] compressVideo(MultipartFile multipartFile,Integer maxFileSize,Integer maxVideoBitRate){
        System.out.println("视频压缩开始");
        long startTime=System.currentTimeMillis();
        try {
            byte[] fileBytes=multipartFile.getBytes();
            System.out.println("视频原始大小："+fileBytes.length);
            if(fileBytes.length<=maxFileSize*1024*1024){
                return fileBytes;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        //获取文件名
        String fileName = multipartFile.getOriginalFilename();

        //获取临时存储路径
        String tempDirPath = getTempDirPath();
        File tempDir = new File(tempDirPath);
        if(!tempDir.exists()){
            tempDir.mkdir();
        }

        File source=new File(tempDirPath+fileName);

        try {
            FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), source);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        MultimediaObject obj = new MultimediaObject(source);

        AudioInfo audioInfo=null;
        VideoInfo videoInfo=null;
        int second=0;
        try {
            //获取文件视频，音频时长等信息
            audioInfo = obj.getInfo().getAudio();
            videoInfo = obj.getInfo().getVideo();
            second = (int) (obj.getInfo().getDuration() / 1000);
        }  catch (InputFormatException e) {
            e.printStackTrace();
        } catch (EncoderException e) {
            e.printStackTrace();
        }
        long fileSize = source.length();


        // 视频属性设置(包含音频)
        int maxBitRate = 128000;    //音频最大码率
        int maxSamplingRate = 22050;    //音频采样率
//        int maxVideoBitRate = 800000;       //视频码率  相当于每秒视频 100KB左右
        int maxFrameRate = 15;      //视频帧率

        File target=new File(tempDirPath+"_"+fileName);


        try {

            AudioAttributes audio= new AudioAttributes();
            audio.setCodec("libmp3lame");   //设置编码
            audio.setBitRate(new Integer(audioInfo.getBitRate()>maxBitRate?maxBitRate:audioInfo.getBitRate()));
            audio.setChannels(new Integer(1));  //设置声道数 单声道
            audio.setSamplingRate(new Integer(audioInfo.getSamplingRate()>maxSamplingRate?maxSamplingRate:audioInfo.getSamplingRate()));




            VideoAttributes video=new VideoAttributes();
            video.setCodec("h264");     //

            //            小于八兆不压缩
            //            先按最大码率计算压缩后大小，如果大于8M的话，直接压缩到8M，否则，按最大码率压缩
            if(fileSize>maxFileSize*1024*1024){
                //文件大与8M
                if(maxVideoBitRate*second/8>maxFileSize*1024*1024){
                    //按最大码率压缩后大于8M
                    video.setBitRate(getBitRate(second));
                }else{
                    video.setBitRate(maxVideoBitRate);
                }
            }

            if(videoInfo.getFrameRate()>maxFrameRate){
                video.setFrameRate(maxFrameRate);
            }
            EncodingAttributes attr=new EncodingAttributes();
            attr.setFormat("mp4");
            attr.setAudioAttributes(audio);
            attr.setVideoAttributes(video);
            Encoder encoder=new Encoder();


            encoder.encode(obj,target,attr);

            byte[] bytes= FileUtils.readFileToByteArray(target);
            source.delete();
            target.delete();
            System.out.println("视频压缩后大小："+bytes.length);
            System.out.println("压缩视频花费时间："+(System.currentTimeMillis()-startTime)+"毫秒");
//            encoder.encode(source, target, attr);
            System.out.println("视频压缩结束");
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 压缩视频 默认最高码率为 800000
     * @param multipartFile     数据源
     * @param maxFileSize       压缩后最大体积 指视频大小，不包含音频内容，加上音频后文件总大小稍大于这个值 1-2M （单位：MB）
     * @return
     */
    public static byte[] compressVideo(MultipartFile multipartFile,Integer maxFileSize) {
        return compressVideo(multipartFile,maxFileSize,800000);
    }

    //获取存储临时文件的路径
    private static String getTempDirPath(){
        String path = VideoUtil.class.getResource("/").getPath();
        char lastCh = path.charAt(path.length() - 1);
        if(lastCh=='/'){
            path=path.substring(0,path.length()-1);
        }
        path = path.substring(0, path.lastIndexOf('/') + 1);
        return path+"temp/";
    }


    //MultipartFile类写入文件file
    private boolean multipart2File(MultipartFile multipartFile,File file){

        try {
            FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    //读取文件file为 byte数组
    private byte[] File2bytes(File file){
        byte[] bytes=null;
        try {
            bytes=FileUtils.readFileToByteArray(file);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return bytes;
    }

    //获取适合码率将目标视频压缩到8M左右
    private static int getBitRate(int second){
        return 8*1024*1024*8/second/1000*1000;
    }
}
